<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="utf-8">
    <meta http-equiv="cache-control" content="no-cache, no-store, must-revalidate">
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache" content="no-cache">
    <meta http-equiv="expires" content="0">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
    <title>连星五子棋</title>
<style>
    html, body{
        margin: 0;
        padding: 0;
    }
    body{
        width: 100vw;
        height: 100vh;
        text-overflow: ellipsis;
        white-space: nowrap;
        overflow: auto;
    }

    pre, ul, input,select{
        margin: 0;
        padding: 0;
    }
    input,select{
        background-color: transparent;
        border: none;
        outline: none;
    }
    a{
        color:black;
    }
    label, .label{
        cursor: default;
        -webkit-touch-callout: none;
        -webkit-user-select: none;
        -khtml-user-select: none;
        -moz-user-select: none;
        -ms-user-select: none;
        user-select: none;
    }
    html{
        font-size: 4vh;
    }
    body{
        margin: 0 auto;
        display: flex;
        flex-flow: column nowrap;
        justify-content: space-between;
        align-items: center;
        width: 100vw;
        height: 100vh;
    }
    .button{
        cursor: pointer;
        user-select: none;
    }

    #top{
        flex-shrink: 0;
        display: flex;
        flex-flow: row nowrap;
        justify-content: space-around;
        align-items: center;
        width: 100%;
        min-height: 2rem;
        max-height: 2rem;
        background-color: #a2a2a2;
    }
    #top-title{
        color: #dddddd;
        font-size: 80%;
    }

    #box{
        flex-shrink: 1;
        flex-grow: 2;
        display: flex;
        flex-flow: row nowrap;
        justify-content: center;
        align-items: center;
        width: 100%;
        background-color: #606060;
        overflow: auto;
    }
    #box .button{
        background-color: #7f7f7f;
        color: #dddddd;
        cursor: pointer;
    }
    #box .button:hover{
        background-color: #9f9f9f;
        color: #eeeeee;
    }
    #box .hline{
        background-color: #999999;
        width: 100%;
        height: 1pt;
    }

    #box-newgame{
        align-items: center;
        width: 100%;
        height: 100%;
        min-height: 100%;
    }
    #box-newgame .in{
        margin: 0 auto;
        margin-top: 2px;
        width: 96%;
    }
    #box-newgame .in .row{
        display: flex;
        flex-flow: row nowrap;
        justify-content: flex-start;
        align-items: baseline;
        width: 100%;
        min-height: 1.6rem;
        line-height: 1.6rem;
        font-size: 0.8rem;
        font-family: "隶属","宋体","微软雅黑";
        border-top: 1px dashed #7f7f7f;
        border-bottom: 1px dashed #7f7f7f;
        margin-top: 0.2rem;
        margin-bottom: 0.2rem;
    }
    #box-newgame .in .row:hover{
        border-color: #cccccc;
    }
    #box-newgame .in .row .label{
        color: #aaaaaa;
        width: 39%;
        font-size: 1em;
    }
    #box-newgame .in .row .right-line{
        display: flex;
        flex-flow: row nowrap;
        justify-content: flex-start;
        align-items: center;
        width: 60%;
        height: 100%;
        color: #BBBBBB;
    }
    #box-newgame .in .row .right-line label{
        min-width: 3em;
    }
    #box-newgame .in .row .right{
        display: flex;
        flex-flow: column nowrap;
        justify-content: flex-start;
        align-items: flex-start;
        width: 60%;
        color: #BBBBBB;
    }
    #box-newgame .in select{
        border-bottom: 1px solid #3f3f3f;
        color: #aaaaaa;
        min-width: 7em;
        height: 1.2em;
        font-size: 0.9em;
        text-align: center;
    }
    #newgame-cmd-start{
        margin: 0 auto;
        text-align: center;
        width: 4rem;
    }
    #box-newgame .button{
        font-family: "隶书","黑体","微软雅黑";
        font-size: 0.9rem;
        height: 1.2rem;
        line-height: 1.2rem;
        padding-left: 1rem;
        padding-right: 1rem;
    }
    #box-newgame .hline{
        margin-top: 0.6rem;
        margin-bottom: 0.6rem;
    }

    #box-game{
        display: flex;
        flex-flow: column nowrap;
        justify-content: flex-start;
        align-items: center;
        width: 100%;
        height: 100%;
    }

    #box-game .top-infos{
        display: flex;
        flex-flow: column nowrap;
        justify-content: flex-start;
        align-items: center;
        width: 98%;
        min-height: 1.1rem;
        line-height: 1.1rem;
        margin-top: 4px;
        margin-bottom: 4px;
    }
    #box-game .top-infos .row{
        background-color: #777777;
        display: flex;
        flex-flow: row nowrap;
        justify-content: flex-start;
        align-items: center;
        width: 100%;
        height: 1.1rem;
        line-height: 1.1rem;
        font-size: 0.8rem;
        margin-bottom: 1px;
        user-select: none;
    }
    #box-game .top-infos .row .left{
        background-color: #888888;
        color: #bbbbbb;
        min-width: 3em;
        max-width: 3em;
        text-align: right;
    }
    #box-game .top-infos .row .right{
        color: #aaaaaa;
        font-size: 0.8em;
        text-align: center;
        width: 100%;
    }
    #box-game .top-infos .row .cur-player{
        color: #dddddd;
    }

    #game-chessboard{
        flex-shrink: 0;
        background-color: #ffb45b;
        border: 1px solid #101010;
        margin-bottom: 2px;
    }

    #box-game .tools-line{
        display: flex;
        flex-flow: row nowrap;
        justify-content: space-between;
        align-items: center;
        width: 98%;
        min-height: 1rem;
        max-height: 1rem;
        line-height: 1rem;
        margin-top: 2px;
        margin-bottom: 2px;
        font-size: 0.75rem;
        font-family: "隶书","黑体","宋体";
        color: #999999;
    }
    #box-game .tools-line .item{
        height: 100%;
        min-width: 2.5em;
        text-align: center;
        user-select: none;
    }

    #box-setting{
        width: 95%;
        height: 95%;
        overflow: visible;
    }
    #box-setting .row{
        display: flex;
        flex-flow: row nowrap;
        justify-content: space-between;
        align-items: center;
        color: #BBBBBB;
        font-size: 0.8rem;
        height: 1.5rem;
        line-height: 1.5rem;
        width: 100%;
        margin-top: 0.5rem;
        margin-bottom: 0.5rem;
        user-select: none;
        cursor: default;
    }
    #box-setting .row .left{
        font-family: "隶书","楷体","宋体";
        width: 49%;
        text-align: right;
    }
    #box-setting .row .right{
        color: #aaaaaa;
        width: 50%;
        text-align: center;
    }
    #box-setting select{
        border-bottom: 1px solid #3f3f3f;
        color: #aaaaaa;
        min-width: 7em;
        height: 1.2em;
        font-size: 0.9em;
        text-align: center;
    }
    #box-setting .title{
        background-color: #888888;
        color: #666666;
        font-size: 0.9rem;
        text-align: center;
        height: 1.2rem;
        line-height: 1.2rem;
        width: 100%;
    }

    #box-about{
        display: flex;
        flex-flow: column nowrap;
        justify-content: flex-start;
        align-items: start;
        width: 100%;
        height: 100%;
        overflow-y: auto;
        overflow-x: hidden;
        padding-left: 0.2rem;
        padding-right: 0.2rem;
        white-space: normal;
    }
    #box-about .title{
        margin-top: 0.2rem;
        color: #AAAAAA;
        font-size: 0.8rem;
        width: 100%;
    }
    #box-about .part{
        margin-top: 0.6rem;
        color: #999999;
        font-size: 0.6rem;
        width: 100%;
    }

    #tabs{
        flex-shrink: 0;
        display: flex;
        flex-flow: row nowrap;
        justify-content: space-around;
        align-items: center;
        width: 100%;
        min-height: 3rem;
        max-height: 3rem;
        background-color: #202020;
    }
    #tabs .label{
        flex-basis:4rem;
        flex-grow: 1;
        display: flex;
        flex-flow: row nowrap;
        justify-content: center;
        align-items: center;
        font-family: "楷体","宋体","黑体";
        font-size: 80%;
        color: #aaaaaa;
        height: 100%;
        cursor: pointer;
    }
    #tabs .label:hover{
        color: #dddddd;
    }
    #tabs .label-cur{
        background-color: #303030;
        color: #eeeeee;
        text-shadow: -1px 1px #505050;
    }
</style>
</head>
<body style="display: none;">
    <div id="top"><label id="top-title"></label></div>
    <div id="box">
        <div id="box-newgame" ux-box="newgame" style="display: none;">
            <div class="in">
                <div class="row">
                    <div class="label">规则</div>
                    <div class="right">
                        <label><input name="newgame-in-rule" type="radio" ux-value="无禁手"/>无禁手</label>
                        <label><input name="newgame-in-rule" type="radio" ux-value="仅禁手"/>仅禁手</label>
                        <label><input name="newgame-in-rule" type="radio" ux-value="一手交换"/>一手交换</label>
                        <label><input name="newgame-in-rule" type="radio" ux-value="五手三打"/>五手三打</label>
                        <label><input name="newgame-in-rule" type="radio" ux-value="五手五打"/>五手五打</label>
                    </div>
                </div>
                <div class="row">
                    <div class="label">总时限</div>
                    <div class="right-line">
                        <select id="newgame-in-maxtime-total" title="不能小于单步时限的一半">
                            <option ux-value="600">10分钟</option>
                            <option ux-value="1200">20分钟</option>
                            <option ux-value="1800">30分钟</option>
                            <option ux-value="3600">1小时</option>
                            <option ux-value="5400">1小时30分钟</option>
                            <option ux-value="10800">3小时</option>
                        </select>
                    </div>
                </div>
                <div class="row">
                    <div class="label">单步时限</div>
                    <div class="right-line">
                        <select id="newgame-in-maxtime-step" title="不能大于总时限的一半">
                            <option ux-value="60">1分钟</option>
                            <option ux-value="120">2分钟</option>
                            <option ux-value="300">5分钟</option>
                            <option ux-value="600">10分钟</option>
                            <option ux-value="1200">20分钟</option>
                            <option ux-value="1800">30分钟</option>
                            <option ux-value="3600">60分钟</option>
                        </select>
                    </div>
                </div>
                <div class="row" title="选择AI接管的执棋方">
                    <div class="label">AI</div>
                    <div class="right-line">
                        <label><input name="newgame-in-use-ai" type="checkbox" ux-value="0"/>黑棋</label>
                        <label><input name="newgame-in-use-ai" type="checkbox" ux-value="1"/>白棋</label>
                    </div>
                </div>
            </div>
            <div class="hline"></div>
            <div style="margin: 0 auto; width: 96%;">
                <div id="newgame-cmd-start" class="button label">开始</div>
                <div style="height: 0.5rem; width: 100%;"></div>
            </div>
        </div>
        <div id="box-game" ux-box="game" style="display: none;">
            <div class="top-infos">
                <div class="row">
                    <div class="left">对局</div>
                    <div class="right">
                        <label id="game-info-rule" title="当前对局使用的规则"></label>
                        <label id="game-info-maxtime" title="当前对局每步/总共时限"></label>
                    </div>
                </div>
                <div class="row">
                    <div class="left">时限</div>
                    <div class="right">
                        <label id="game-info-timer-black" title="黑棋剩余时间"></label>
                        <label id="game-info-timer-white" title="白棋剩余时间"></label>
                    </div>
                </div>
                <div class="row">
                    <div class="left">状态</div>
                    <div class="right">
                        <label id="game-info-status"></label>
                    </div>
                </div>
            </div>
            <canvas id="game-chessboard"></canvas>
            <div class="tools-line">
                <div class="item button" title="由AI接管黑棋"><label><input id="game-use-ai-black" type="checkbox"/>AI执黑</label></div>
                <div class="item button" title="由AI接管白棋"><label><input id="game-use-ai-white" type="checkbox"/>AI执白</label></div>
                <div id="game-cmd-load-first" class="item button" title="后退至初局">▲</div>
                <div id="game-cmd-prev" class="item button" title="后退一步">◀</div>
                <div id="game-cmd-next" class="item button" title="前进一步">▶</div>
                <div id="game-cmd-load-last" class="item button" title="前进至终局">▼</div>
            </div>
            <div class="tools-line">
                <div id="game-cmd-restart" class="item button" title="重新开始对局">重开</div>
                <div id="game-cmd-load" class="item" title="从保存的对局中恢复游戏(暂未开放)">加载</div>
                <div id="game-cmd-save" class="item" title="保存当前对局(暂未开放)">保存</div>
                <div id="game-cmd-giveup" class="item" title="投子认输">投子</div>
                <div id="game-cmd-swap" class="item" title="当有一方为AI时，交换玩家和AI的执棋方" ux-a="已交换" ux-b="交换"></div>
            </div>
        </div>
        <div id="box-setting" ux-box="setting" style="display: none;">
            <div class="title label">AI</div>
            <div class="row" title="AI模拟对局次数上限">
                <div class="left">最大模拟次数</div>
                <div class="right">
                    <select id="set-uct-max-time">
                        <option ux-value="16384">16384</option>
                        <option ux-value="32768">32768</option>
                        <option ux-value="65536">65536</option>
                        <option ux-value="262144">262144</option>
                    </select>
                </div>
            </div>
            <div class="row" title="AI连续取胜路线检测深度">
                <div class="left">VCT检测深度</div>
                <div class="right">
                    <select id="set-vc-max-depth">
                        <option ux-value="16">16</option>
                        <option ux-value="24">24</option>
                        <option ux-value="32">32</option>
                        <option ux-value="40">40</option>
                        <option ux-value="48">48</option>
                        <option ux-value="56">56</option>
                        <option ux-value="64">64</option>
                    </select>
                </div>
            </div>
            <div class="row" title="AI搜索深度">
                <div class="left">AI搜索深度</div>
                <div class="right">
                    <select id="set-search-depth">
                        <option ux-value="4">4</option>
                        <option ux-value="6">6</option>
                        <option ux-value="8">8</option>
                        <option ux-value="10">10</option>
                        <option ux-value="12">12</option>
                        <option ux-value="14">14</option>
                        <option ux-value="16">16</option>
                    </select>
                </div>
            </div>
        </div>
        <div id="box-about" ux-box="about" style="display: none;">
            <div class="title">连星五子棋(低算力WEB版)</div>
            <div class="part">by clonne/2023</div>
            <div class="part">
                连星WEB版是一个桌面电脑与手机移动端都能使用的五子棋AI对战程序，目前实现了基本的无禁手和一手交换规则，以及单重非递归的禁手：
                黑棋在一个点形成四四/三三/长连即判定为禁手，但不对构成禁手的棋形进一步递归检查是否为可下点，只是对这个点的单重分析，没有使用相对标准的定义，慎用。
                虽然现行禁手规则本身就存在问题，特别是复杂局面，但我也会长期跟进，尽快实现较为标准的禁手判断。
            </div>
            <div class="part">
                本程序的AI使用VCT(连续取胜路线搜索)与UCT(MCTS+UCB)算法，受限于浏览器JavaScript的性能限制，目前只能进行浅层低规模的分析。
            </div>
            <div class="part">
                目前的AI有以下参数：<br/>
                【最大思考深度】主要用于设置UCT的模拟次数，每个深度模拟65536次<br/>
                【VCT检测深度】搜索连续取胜路线时能达到的最深步数<br/>
                这些参数对于移动端都不能开太高
            </div>
            <div class="part" style="line-height: 1rem;">
                Thanks:<br/>
                Gitee<br/>
                VSCode<br/>
                Edge<br/>
            </div>
        </div>
    </div>
    <div id="tabs">
        <div id="tabs-to-newgame" class="label">新游戏</div>
        <div id="tabs-to-game" class="label">对局</div>
        <div id="tabs-to-setting" class="label">设置</div>
        <div id="tabs-to-about" class="label">关于</div>
    </div>
</body>
<script>document.write(((a,b)=>(`${a}t type="module" src="./main.js?fuck=${Date.now()}">${b}t>`))("<scrip","</scrip"))</script>
</html>
